//
//  ViewController.m
//  myAccelerometerDemo2
//
//  Created by yorkfeng on 15/12/13.
//  Copyright © 2015年 yorkfeng. All rights reserved.
//

#import "ViewController.h"
#import <CoreMotion/CoreMotion.h>

@interface ViewController () {
    CMMotionManager *motionManager;
    __weak IBOutlet UILabel *lab1;
    __weak IBOutlet UILabel *lab2;
    __weak IBOutlet UILabel *lab3;
    __weak IBOutlet UILabel *lab4;
    __weak IBOutlet UILabel *lab5;
    __weak IBOutlet UILabel *lab6;
    __weak IBOutlet UILabel *lab7;
    __weak IBOutlet UILabel *lab8;
    __weak IBOutlet UILabel *lab9;
    __weak IBOutlet UILabel *lab10;
    __weak IBOutlet UILabel *lab11;
    __weak IBOutlet UILabel *lab12;
    __weak IBOutlet UILabel *lab13;
    __weak IBOutlet UILabel *lab14;
    __weak IBOutlet UILabel *lab15;
    __weak IBOutlet UILabel *lab16;
    __weak IBOutlet UILabel *lab17;
    __weak IBOutlet UILabel *lab18;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    motionManager = [[CMMotionManager alloc] init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)startBtn:(id)sender {
    if (!motionManager.accelerometerAvailable) {
        // fail code // 检查传感器到底在设备上是否可用
    }
    
    motionManager.accelerometerUpdateInterval = 0.01; // 告诉manager，更新频率是100Hz
    motionManager.deviceMotionUpdateInterval = 0.01;
    
    //pull方式,motionManager.xxxData即可随时可用，并反应当前数据
    //能够以CoreMotionManager的只读方式获取当前任何传感器状态或是组合数据；
//    [motionManager startAccelerometerUpdates]; // 开始更新，后台线程开始运行。这是pull方式。
//    [motionManager startDeviceMotionUpdates];
    
    
    //push方式,根据给定的更新周期按一定频率被调用
    //是以块或者闭包的形式收集到想要得到的数据并且在特定周期内得到实时的更新；
    [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *latestAcc, NSError *error)
     {
         // Your code here
         
         //1. Accelerometer 获取手机加速度数据
         CMAccelerometerData *newestAccel = motionManager.accelerometerData;
         double accelerationX = newestAccel.acceleration.x;
         double accelerationY = newestAccel.acceleration.y;
         double accelerationZ = newestAccel.acceleration.z;
         [lab1 setText:[NSString stringWithFormat:@"加速度x：%f",accelerationX]];
         [lab2 setText:[NSString stringWithFormat:@"加速度y：%f",accelerationY]];
         [lab3 setText:[NSString stringWithFormat:@"加速度z：%f",accelerationZ]];
    }];
    
    [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *latestAcc, NSError *error)
     {
         //2. Gravity 获取手机的重力值在各个方向上的分量，根据这个就可以获得手机的空间位置，倾斜角度等
         double gravityX = motionManager.deviceMotion.gravity.x;
         double gravityY = motionManager.deviceMotion.gravity.y;
         double gravityZ = motionManager.deviceMotion.gravity.z;
         [lab4 setText:[NSString stringWithFormat:@"重力值在x方向上的分量：%f",gravityX]];
         [lab5 setText:[NSString stringWithFormat:@"重力值在y方向上的分量：%f",gravityY]];
         [lab6 setText:[NSString stringWithFormat:@"重力值在z方向上的分量：%f",gravityZ]];
         
         //获取手机的倾斜角度：
         //zTheta是手机与垂直面的夹角， xyTheta是手机绕自身旋转的角度
         //3. DeviceMotion 获取陀螺仪的数据 包括角速度，空间位置等
         double zTheta = atan2(gravityZ,sqrtf(gravityX*gravityX+gravityY*gravityY))/M_PI*180.0;
         double xyTheta = atan2(gravityX,gravityY)/M_PI*180.0;
         [lab7 setText:[NSString stringWithFormat:@"手机与垂直面的夹角：%f",zTheta]];
         [lab8 setText:[NSString stringWithFormat:@"手机绕自身旋转的角度：%f",xyTheta]];
         
         
         //旋转角速度：
         CMRotationRate rotationRate = motionManager.deviceMotion.rotationRate;
         double rotationX = rotationRate.x;
         double rotationY = rotationRate.y;
         double rotationZ = rotationRate.z;
         [lab9 setText:[NSString stringWithFormat:@"旋转角速度x：%f",rotationX]];
         [lab10 setText:[NSString stringWithFormat:@"旋转角速度y：%f",rotationY]];
         [lab11 setText:[NSString stringWithFormat:@"旋转角速度z：%f",rotationZ]];
         
         //空间位置的欧拉角（通过欧拉角可以算得手机两个时刻之间的夹角，比用角速度计算精确地多）
         double roll = motionManager.deviceMotion.attitude.roll;
         double pitch = motionManager.deviceMotion.attitude.pitch;
         double yaw = motionManager.deviceMotion.attitude.yaw;
         [lab12 setText:[NSString stringWithFormat:@"空间位置的欧拉角x：%f",roll]];
         [lab13 setText:[NSString stringWithFormat:@"空间位置的欧拉角y：%f",pitch]];
         [lab14 setText:[NSString stringWithFormat:@"空间位置的欧拉角z：%f",yaw]];
         
         //空间位置的四元数（与欧拉角类似，但解决了万向结死锁问题）
         double w = motionManager.deviceMotion.attitude.quaternion.w;
         double wx = motionManager.deviceMotion.attitude.quaternion.x;
         double wy = motionManager.deviceMotion.attitude.quaternion.y;
         double wz = motionManager.deviceMotion.attitude.quaternion.z;
         [lab15 setText:[NSString stringWithFormat:@"空间位置的四元数：%f",w]];
         [lab16 setText:[NSString stringWithFormat:@"空间位置的四元数x：%f",wx]];
         [lab17 setText:[NSString stringWithFormat:@"空间位置的四元数y：%f",wy]];
         [lab18 setText:[NSString stringWithFormat:@"空间位置的四元数z：%f",wz]];
     }];
}

- (IBAction)stopBtn:(id)sender {
    [motionManager stopAccelerometerUpdates];
    [motionManager stopDeviceMotionUpdates];
}

@end
